﻿namespace PVRP_SR
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;

    /// <summary>
    /// The sweep.
    /// </summary>
    internal class Sweep : ConstructionHeuristic
    {
        #region Fields

        /// <summary>
        /// The _angles.
        /// </summary>
        private List<KeyValuePair<int, double>> _angles;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Sweep"/> class.
        /// </summary>
        public Sweep()
        {
            this._angles = new List<KeyValuePair<int, double>>();
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The create solution.
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <returns>
        /// The <see cref="PvrpSrSolution"/>.
        /// </returns>
        /// <exception cref="Exception">
        /// </exception>
        public override PvrpSrSolution CreateSolution(TSPLIBParser instance)
        {
            PvrpSrSolution solution = new PvrpSrSolution(instance);
            if (instance.StartDepots.Length != 1)
            {
                throw new Exception("algorithm assumes one depot");
            }

            if (instance.CoordinatesNormalized == false)
            {
                throw new Exception("algorithm assumes that depot is at the origin");
            }

            this.CalculateAngles(instance);

            // sort angles using LINQ in descending order
            this._angles = (from kv in this._angles orderby kv.Value ascending select kv).ToList();

            return solution;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Assign customers using a modification of the Cordeau, Gendreau and Laporte for PVRP
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        /// <param name="solution">
        /// The solution.
        /// </param>
        private void AssignCustomers(TSPLIBParser instance, PvrpSrSolution solution)
        {
            int k = 0; // k denotes the current vehicle are using
            for (int l = 0; l < instance.NumDays; l++)
            {
                // select customer closest to the depot
                int closestCustomer = this._angles.ElementAt(0).Key;
            }
        }

        /// <summary>
        /// The calculate angles.
        /// </summary>
        /// <param name="instance">
        /// The instance.
        /// </param>
        private void CalculateAngles(TSPLIBParser instance)
        {
            for (int i = 1; i < instance.NumNodesRegular; i++)
            {
                this._angles.Add(
                    new KeyValuePair<int, double>(i, Math.Atan2(instance.Vertices[i][1], instance.Vertices[i][0])));
                Debug.Assert(this._angles[i - 1].Value >= 0 && this._angles[i - 1].Value <= Math.PI * 2.0);
            }
        }

        #endregion
    }
}